home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 October: Mac OS SDK / Dev.CD Oct 96 SDK / Dev.CD Oct 96 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / ODFDev / ODF / Found / FWStream / Include / FWArcObj.fr next >
Encoding:
Text File  |  1996-08-16  |  5.6 KB  |  141 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                FWArcObj.fr
  4. //    Release Version:    $ ODF 1 $
  5. //
  6. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #ifndef FWARCOBJ_FR
  11. #define FWARCOBJ_FR
  12.  
  13. #ifndef FWARCOBJ_K
  14. #include "FWArcObj.k"
  15. #endif
  16.  
  17. //========================================================================================
  18. // Theory of operation
  19. //
  20. //    The FWStream subsystem can "archive" objects to and from streams.  Archiving involves
  21. //    converting an object between it's in-memory layout and a flattened representation.
  22. //    The flattened representation is annotated with information that allows the FWStream
  23. //    subsystem to preserve the runtime type of the object.  The format of the annotation
  24. //    is relatively simple.  
  25. //
  26. //        <object-stream> := <class-label> <object-data>
  27. //        <class-label> := <object-header> [ <long ID> ]
  28. //        <object-data> := <object-header> [ <class-specific-data> ]
  29. //        <object-header> := <Tag> <Registry-ID>
  30. //        <Tag> := short integer enumeration { FW_kPrivIDOnly, FW_kPrivIDAndValue }
  31. //        <Registry-ID> := long integer
  32. //
  33. //  Basically, each archivable object is written as a class "label" followed by the
  34. //    instance data of the object.  The label must be specified by the programmer, and
  35. //    is usually closely related to the class name.  The label is intentionally not exactly
  36. //    the class name, since by making it independent of the class name we allow for multiple
  37. //    revisions of the class to exist.  The class label is written out as an object "header"
  38. //    followed by a pascal string (a length byte followed by a maxium of 255 bytes). The
  39. //    object header is a "tag" which identifies how to interpret the registry-ID and also
  40. //    serves another purpose to be described below.  The Registry-ID is usually a 
  41. //    positive integer that must be unique per object in the stream.  However, the Registry
  42. //    ID may also be an integer that has already been seen earlier in the data stream, in
  43. //    which case there will be no object data following the object header.  This is not
  44. //    just a space optimization, it is necessary to prevent a graph data structure from 
  45. //    being converted into a tree data structure.
  46. //
  47. //========================================================================================
  48.  
  49.  
  50. //========================================================================================
  51. // type FW_RObjectWithID
  52. //========================================================================================
  53.  
  54. //
  55. //    Both class-labels and object-datas (see above) are tagged with unique IDs.  
  56. //  The unique IDs must come from the same ID space.  
  57. //    This base type defines the ID space.
  58. //
  59.  
  60. type FW_RObjectWithID
  61. {
  62.     static gUniqueObjectID = 0;
  63.     set gUniqueObjectID = gUniqueObjectID + 1;
  64. };
  65.  
  66. //========================================================================================
  67. // type FW_RArchivableClassHeader
  68. //========================================================================================
  69.  
  70. type FW_RArchivableClassHeader : FW_RObjectWithID
  71. {
  72.     static gClassID = 0;
  73.     set gClassID = gUniqueObjectID;
  74. ClassTag:
  75.     integer = FW_kPrivIDAndValue;
  76. ClassID:
  77.     longint = gClassID;
  78. };
  79.  
  80. //========================================================================================
  81. // type FW_RArchivableObjectHeader
  82. //========================================================================================
  83.  
  84. type FW_RArchivableObjectHeader : FW_RObjectWithID
  85. {
  86.     static gObjectID = 0;
  87.     set gObjectID = gUniqueObjectID;
  88. ObjectTag:
  89.     integer = FW_kPrivIDAndValue;
  90. ObjectID:
  91.     longint = gObjectID;
  92. };
  93.  
  94. //========================================================================================
  95. // type FW_RArchivableObject
  96. //========================================================================================
  97.  
  98. //
  99. //    Any object in a stream is composed of a <class-label> followed by an <object-data>.
  100. //    This type imposes that basic structure.
  101. //
  102. //    Unfortunately, it's not quite the ideal definition.  We currently define this type
  103. //    with an explicit pstring for the class-label string.  This precludes the ability
  104. //    to use the object registry for classes that have already been seen in the stream.
  105. //    This is not a serious problem because there is no general way in ODFrc to recognize
  106. //    repeated occurences of class labels.  The main problem is that archivable object
  107. //    resource streams are bigger than they need to be due to redundant class labels.
  108. //
  109. //  We may someday fix the the problem by some clever use of the ability to preregister
  110. //    class labels.  This would allow us to generate smaller resources, but would still
  111. //    be backwards compatible with the current format, since the Archiver code already
  112. //    handles both cases.
  113. //
  114.  
  115. type FW_RArchivableObject
  116. {
  117.     FW_RArchivableClassHeader;
  118. Label:
  119.     longint = 'badl';                // the id for the class-label
  120.     FW_RArchivableObjectHeader;        // The object-header for the data to follow (in subtype)
  121. };
  122.  
  123. //========================================================================================
  124. // type FW_RArchivableObjectList
  125. //========================================================================================
  126.  
  127. // This definition may be used for any list of archivable objects, but it is better
  128. // treated as a template.  Instead of ObjectArray being an array of FW_RArchivableObject,
  129. // make it be an array of some subclass of FW_RArchivableObject.
  130.  
  131. type FW_RArchivableObjectList('oLST') : FW_RArchivableObject(Label='list')
  132. {
  133.     longint = $$CountOf(ObjectArray);
  134.     array ObjectArray
  135.     {
  136.         FW_RArchivableObject;
  137.     };
  138. };
  139.  
  140. #endif
  141.